﻿import sys
import csv
import odf.opendocument
import os
import sys

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class CsvTable(object):
    def __init__(self, path):
        self.table = {}
        maxcol = 0
        with open(path, "rb") as f:
            rowno = 0
            for row in csv.reader(f):
                colno = 0
                for col in row:
                    self.table[(rowno, colno)] = col
                    colno += 1
                if colno > maxcol: maxcol = colno
                rowno += 1
        self._rows = rowno
        self._cols = maxcol
        
    def getrow(self, rowno):
        for colno in range(self._cols):
            yield colno, self[rowno, colno]
        
    def __getitem__(self, key):
        if key not in self.table:
            return ""
        return self.table[key]
        
    def __getslice__(self, start, end):
        pass
        
    def __str__(self):
        return "rows: {0}\ncols: {1}".format(self._rows, self._cols)

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

def p2str(p):
    L = []
    for node in p.childNodes:
        if node.tagName == "Text":
            L.append(node.data)
        elif node.tagName == "text:s":
            count = 2
            ns = node.get_knownns("text")
            if (ns, "c") in node.attributes:
                count = int(node.attributes[(ns, "c")]) + 1
            L.append(" "*count)
        elif node.tagName == "text:span":
            L.append(str(node))
        else:
            raise Exception("unknown tag in <p>: {0}".format(node.tagName))
    return "".join(L)
    
def cell2str(cell):
    # 줄마다 하나씩의 p태그가 있다.
    value = []
    for p in cell.childNodes:
        value.append(p2str(p).strip())
    return "\r\n".join(value)

    
class Row(object):
    def __init__(self, row=None):
        self.cells = {}
        self.keys = []
        if row:
            colno = 0
            for cell in row.childNodes:
                count = 1
                attr = cell.attributes
                ns = row.get_knownns("table")
                if (ns, "number-columns-repeated") in attr: 
                    count = int(attr[(ns, "number-columns-repeated")])
                if cell and cell.childNodes:
                    value = cell2str(cell)
                    if value:
                        for i in range(colno, colno + count):
                            self.keys.append(i)
                            self.cells[i] = value
                colno += count
        
    def lastcolno(self):
        try:
            return self.keys[-1]
        except IndexError:
            return 1
            
    def isEmpty(self):
        return len(self.cells) == 0
        
    def __getitem__(self, index):
        if index in self.cells:
            return self.cells[index]
        return ""
        
    def __getslice__(self, start, end):
        _end = self.lastcolno() + 1
        if end > _end:
            end = _end
        L = []
        for i in range(start, end):
            L.append(self[i])
        return L
        
    def __repr__(self):
        return repr(self.cells)

    def __unicode__(self):
        L = []
        for key in self.keys:
            value = self.cells[key]
            L.append(value)
        return "\t".join(L)


class Table(object):
    def __init__(self, node=None):
        self.name = ""
        self.rows = {}
        self.keys = []
        if node:
            self.load(node)

    def load(self, table):
        self.name = table.getAttribute("name")
        rowno = 0
        for row in table.childNodes:
            if row.tagName == "table:table-row":
                count = 1
                attr = row.attributes
                ns = row.get_knownns("table")
                if (ns, "number-rows-repeated") in attr: 
                    count = int(attr[(ns, "number-rows-repeated")])
                _row = Row(row)
                if not _row.isEmpty():
                    for i in range(rowno, rowno + count):
                        self.keys.append(i)
                        self.rows[i] = _row
                rowno += count
                
    def lastrowno(self):
        try:
            return self.keys[-1]
        except IndexError:
            return 1

    def lastcolno(self):
        last = 1
        for row in self.rows.values():
            if last < row.lastcolno():
                last = row.lastcolno()
        return last
        
    def toCsv(self, path):
        f = open(path, "wb")
        w = csv.writer(f, quoting=csv.QUOTE_ALL)
        cols = range(1, self.lastcolno() + 1)
        for rowno in range(1, self.lastrowno() + 1):
            row = self[rowno]
            _row = []
            for i in cols:
                _row.append(row[i].encode("utf-8"))
            w.writerow(_row)
        f.close()

    def __getitem__(self, index):
        if index in self.rows:
            return self.rows[index]
        return Row()

    def __unicode__(self):
        L = [self.name]
        L.append(unicode(self.rows[1]))
        return "\n".join(L)
        
        
class Workbook(dict):
    def __init__(self):
        dict.__init__(self)
    
    def load(self, ods):
        self.doc = odf.opendocument.load(ods)
        for node in self.doc.spreadsheet.childNodes:
            if node.tagName == "table:table":
                table = Table(node)
                self[table.name] = table
        return self
        
        
def extract(ods):
    return Workbook().load(ods)
